/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.editor.sheet;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import self.amigo.editor.APropertySheet;
import self.amigo.editor.cmd.PropertiesChange;
import self.amigo.elem.AGraphicElement;
import self.amigo.elem.FillableFeature;
import self.amigo.elem.TextView;
import self.awt.layout.VerticalFlowLayout;
import self.gee.IEditableElement;
import self.gee.editor.IPropertySheet;
import self.lang.BooleanUtils;

public class TextSheet extends APropertySheet implements IPropertySheet {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  JTabbedPane         propertySheet = new JTabbedPane();
  BorderLayout        contentPaneLayout = new BorderLayout();
  JPanel              generalTab = new JPanel();
  VerticalFlowLayout  generalPaneLayout = new VerticalFlowLayout();
  JPanel              generalPane = new JPanel();
  JScrollPane         generalScroller = new JScrollPane();
  BorderLayout        generalLayout = new BorderLayout();

  JLabel              textLabel = new JLabel();
  JTextArea           text = new JTextArea();
  JScrollPane         textScroller = new JScrollPane();
  JCheckBox background = new JCheckBox();
  JComboBox fontName = new JComboBox();
  JComboBox fillColor = new JComboBox();
  JLabel textColorLabelText = new JLabel();
  JLabel fontSizeLabel = new JLabel();
  JLabel backgroundColorLabelText = new JLabel();
  JLabel fontNameLabel = new JLabel();
  JCheckBox italic = new JCheckBox();
  JCheckBox bold = new JCheckBox();
  JComboBox textColor = new JComboBox();
  JTextField fontSize = new JTextField();
  JLabel frameColorLabelText = new JLabel();
  JComboBox frameColor = new JComboBox();
  JCheckBox frame = new JCheckBox();
  VerticalFlowLayout  fontPaneLayout = new VerticalFlowLayout();
  JPanel     fontPanel = new JPanel();
  JLabel aidLinkLabel = new JLabel();
  JTextField aidLink = new JTextField();

  Border border1;
  TitledBorder titledBorder1;

  JPanel textColorPanel = new JPanel();
  JLabel textColorLabel = new JLabel();
  JButton textColorBtn = new JButton();
  JPanel frameColorPanel = new JPanel();
  JLabel frameColorLabel = new JLabel();
  JButton frameColorBtn = new JButton();
  JPanel backgroundColorPanel = new JPanel();
  JLabel backgroundColorLabel = new JLabel();
  JButton backgroundColorBtn = new JButton();
  FlowLayout flowLayout1 = new FlowLayout();

  private IEditableElement view;
  private String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

  private Font origFont;
  private Color                      currTextColor;
  private Color                      currFrameColor;
  private Color                      currBackgroundColor;

  public TextSheet() {
    try {
      jbInit();
//      fillColor.setModel( APropertySheet.createColorModel() );
//      textColor.setModel( APropertySheet.createColorModel() );
//      frameColor.setModel( APropertySheet.createColorModel() );
      fontName.setModel( new DefaultComboBoxModel(fontNames) );
    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    generalScroller.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );

    generalScroller.addComponentListener( new ComponentAdapter() {
        public void componentResized( ComponentEvent ev ) {
          JComponent c = (JComponent)ev.getSource();
          Insets i = c.getInsets();

          Dimension rst = (Dimension) generalPane.getPreferredSize().clone();
          rst.width = c.getWidth()-i.left-i.right - 17;
          generalPane.setPreferredSize( rst );
          generalPane.revalidate();
        }
      } );

    border1 = new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(134, 134, 134));
    titledBorder1 = new TitledBorder(border1,"Font");
    this.setLayout(contentPaneLayout);

    aidLinkLabel.setDisplayedMnemonic('0');
    aidLinkLabel.setText("aid");
    textLabel.setText("text");
    textLabel.setDisplayedMnemonic('T');
    textLabel.setLabelFor(text);
    text.setRows(10);
    text.setLineWrap(true);
    text.setWrapStyleWord(true);

    background.setSelected(true);
    background.setText("background");
//    background.setHorizontalTextPosition(SwingConstants.LEADING);

    frame.setSelected(false);
    frame.setText("frame");
//    frame.setHorizontalTextPosition(SwingConstants.LEADING);

    textColorLabelText.setText("text color");
    frameColorLabelText.setText("frame color");
    fontSizeLabel.setToolTipText("");
    fontSizeLabel.setText("size");
    fontSize.setColumns(3);
    backgroundColorLabelText.setText("background color");
    fontNameLabel.setText("name");
    italic.setText("italic");
//    italic.setHorizontalTextPosition(SwingConstants.LEADING);
    bold.setText("bold");
//    bold.setHorizontalTextPosition(SwingConstants.LEADING);

    fontPanel.setBorder(titledBorder1);
    textScroller.getViewport().add(text, null);
    generalPane.setLayout(generalPaneLayout);
    generalPane.add(textLabel, null);
    generalPane.add(textScroller, null);

    fontPanel.setLayout( fontPaneLayout );
    fontPanel.add(fontNameLabel, null);
    fontPanel.add(fontName, null);
    fontPanel.add(fontSizeLabel, null);
    fontPanel.add(fontSize, null);
    fontPanel.add(bold, null);
    fontPanel.add(italic, null);
    generalPane.add(fontPanel, null);

//    generalPane.add(textColorLabelText, null);
//    generalPane.add(textColor, null);
    generalPane.add(frame, null);
//    generalPane.add(frameColorLabelText, null);
//    generalPane.add(frameColor, null);
    generalPane.add(background, null);
    generalPane.add( textColorPanel, null );
    generalPane.add( frameColorPanel, null );
    generalPane.add( backgroundColorPanel, null );
//    generalPane.add(backgroundColorLabelText, null);
//    generalPane.add(fillColor, null);

    generalPane.add(aidLinkLabel, null);
    generalPane.add(aidLink, null);

    generalScroller.getViewport().add( generalPane, null );
    generalTab.setLayout(generalLayout);
    generalTab.add( generalScroller, BorderLayout.CENTER );

    flowLayout1.setAlignment(FlowLayout.LEFT);

    textColorLabel.setBackground(new Color(192, 192, 20));
    textColorLabel.setOpaque(true);
    textColorLabel.setText("               ");
    textColorBtn.setPreferredSize(new Dimension(30, 16));
    textColorBtn.setText("...");
    textColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        textColorBtn_actionPerformed(e);
      }
    });
    textColorPanel.setLayout(flowLayout1);
    textColorPanel.add(textColorLabel, null);
    textColorPanel.add(textColorBtn, null);
    textColorPanel.add(new JLabel(" text"), null);

    frameColorLabel.setBackground(new Color(192, 192, 20));
    frameColorLabel.setOpaque(true);
    frameColorLabel.setText("               ");
    frameColorBtn.setPreferredSize(new Dimension(30, 16));
    frameColorBtn.setText("...");
    frameColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        frameColorBtn_actionPerformed(e);
      }
    });
    frameColorPanel.setLayout(flowLayout1);
    frameColorPanel.add(frameColorLabel, null);
    frameColorPanel.add(frameColorBtn, null);
    frameColorPanel.add(new JLabel(" frame"), null);

    backgroundColorLabel.setBackground(new Color(192, 192, 20));
    backgroundColorLabel.setOpaque(true);
    backgroundColorLabel.setText("               ");
    backgroundColorBtn.setPreferredSize(new Dimension(30, 16));
    backgroundColorBtn.setText("...");
    backgroundColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        backgroundColorBtn_actionPerformed(e);
      }
    });
    backgroundColorPanel.setLayout(flowLayout1);
    backgroundColorPanel.add(backgroundColorLabel, null);
    backgroundColorPanel.add(backgroundColorBtn, null);
    backgroundColorPanel.add(new JLabel(" background"), null);

    this.add(propertySheet, BorderLayout.CENTER);
    propertySheet.add(generalTab, "General");
  }

  public void inspect( Object toDisplay ) {
    if ( toDisplay instanceof TextView ) {
      view = (IEditableElement) toDisplay;
      revert();
    } else
      throw new RuntimeException("Invalid Graphic element to display:" + toDisplay );
  }

  public void accept() {
    if ( view == null )
      return;

    String data = text.getText();
    store.put( TextView.TEXT_PROP, data );
    store.put( TextView.AID_PROP,  aidLink.getText() );

    int fontSz;
    try {
      fontSz = Integer.parseInt( fontSize.getText() );
    } catch ( Exception err ) {
      fontSz = origFont.getSize();
    }
    int attrMask = 0;
    if ( bold.isSelected() )
      attrMask |= Font.BOLD;
    if ( italic.isSelected() )
      attrMask |= Font.ITALIC;
    String fontNm = fontNames[ fontName.getSelectedIndex() ];
    Font newFont = new Font( fontNm, attrMask, fontSz );
    store.put( TextView.FONT_PROP, newFont );

    store.put( TextView.SHOWFRAME_PROP, BooleanUtils.toBoolean(frame.isSelected()) );
    store.put( AGraphicElement.FRAMECOLOR_PROP, currFrameColor );

    store.put( TextView.TEXTCOLOR_PROP, currTextColor );

    FillableFeature fillComp = (FillableFeature) store.get( TextView.FILL_PROP );
    if ( background.isSelected() ) {
      fillComp.fillColor = currBackgroundColor;
    } else
      fillComp.fillColor = null;

    PropertiesChange cmd = new PropertiesChange( editor, view, store );
    cmd.executeIfRequired();
  }

  public void revert() {
    if ( view == null )
      return;

    store.clear();
    view.getProperties( store );
    String data = (String) store.get( TextView.TEXT_PROP );
    text.setText( data );
    aidLink.setText( (String) store.get( TextView.AID_PROP ) );

    origFont = (Font) store.get( TextView.FONT_PROP );
    fontName.setSelectedItem( origFont.getName() );
    fontSize.setText( "" + origFont.getSize() );
    bold.setSelected( origFont.isBold() );
    italic.setSelected( origFont.isItalic() );

    frame.setSelected( BooleanUtils.toPrimitive(store.get(TextView.SHOWFRAME_PROP)) );
    currFrameColor = (Color) store.get( AGraphicElement.FRAMECOLOR_PROP );
    frameColorLabel.setBackground( currFrameColor );

    currTextColor = (Color) store.get( TextView.TEXTCOLOR_PROP );
    textColorLabel.setBackground( currTextColor );

    FillableFeature fillComp = (FillableFeature) store.get( TextView.FILL_PROP );
    currBackgroundColor = fillComp.fillColor;
    backgroundColorLabel.setBackground( currBackgroundColor );
    background.setSelected( (currBackgroundColor != null) );
  }

  public Object getObjectUnderInspection() {
    return view;
  }

  void textColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select text color", currTextColor );
    if ( c != null ) {
      currTextColor = c;
      textColorLabel.setBackground( c );
    }
  }

  void frameColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select frame color", currFrameColor );
    if ( c != null ) {
      currFrameColor = c;
      frameColorLabel.setBackground( c );
    }
  }

  void backgroundColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select background color", currBackgroundColor );
    if ( c != null ) {
      currBackgroundColor = c;
      backgroundColorLabel.setBackground( c );
    }
  }

  private Color querySelectColor( String title, Color curr ) {
		return JColorChooser.showDialog( this, title,  curr );
  }

//  static public void main( String[] args ) {
//    JFrame form = new JFrame( "test" );
//    TextSheet sheet = new TextSheet();
//    form.getContentPane().add( sheet );
//    form.show();
//  }
}
